package cn.yeziji.file.service;

import cn.yeziji.file.basic.FileProcess;
import cn.yeziji.file.dto.FileDTO;
import cn.yeziji.file.vo.FileDataVO;
import cn.yeziji.file.vo.FileVO;
import cn.yeziji.forum.basic.file.DirectUploaderFilesInfo;
import cn.yeziji.forum.basic.file.OssRequiredEntry;
import cn.yeziji.forum.basic.file.WebUploader;
import cn.yeziji.forum.basic.pay.PayPathInfo;
import cn.yeziji.forum.common.ForumPageResult;
import cn.yeziji.forum.common.enums.PayFilePrefixEnum;
import cn.yeziji.forum.common.enums.status.FileStatus;
import cn.yeziji.forum.common.key.FileCacheKey;
import cn.yeziji.forum.dto.file.ForumFilePagingDTO;
import cn.yeziji.forum.exception.FileException;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.util.List;

/**
 * 文件服务
 *
 * <p>TODO:整理代码结构
 *
 * @author gzkemays
 * @since 2022/5/12 8:24
 */
public interface FileService {
  long CHUNK_SIZE = 1024L << 10;
  int THREAD_NUM = 4;
  String UPLOAD_PREFIX = "https://img.yeziji.xyz/";
  String MERCHANT_UPLOAD_PREFIX = "http://pay.yziji.xyz";

  /**
   * 获取上传进度
   *
   * @param md5 文件MD5
   * @return 上传的片段
   */
  Integer getProcess(String md5);

  /**
   * 通过本地上传的方式上传
   *
   * @param uploader webuploader 上传方式
   * @return 是否上传成功
   */
  boolean locationUploader(WebUploader uploader);

  /** 上传至阿里云 */
  boolean ossUploader(WebUploader uploader);

  /**
   * 获取数据库的文件数据
   *
   * @param dto 分页参数
   * @return 数据库文件数据
   */
  ForumPageResult<FileDataVO> getDataFiles(ForumFilePagingDTO dto);

  /**
   * 获取文件的下载地址
   *
   * @param file 文件 -- 获取文件名即可
   * @return 文件的下载地址
   */
  FileVO getFile(FileDTO file);

  /**
   * 获取文件列表
   *
   * @param file 文件 -- 指定 rootPath
   * @return rootPath 下所有文件
   */
  List<FileVO> getFiles(FileDTO file);

  /** TODO:获取用户文件列表 */
  List<FileProcess> getUserFiles();

  /**
   * 获取上传码
   *
   * <p>上传码的使用次数为 5 次
   *
   * @param num 上传码数量
   * @return 上传码列表
   */
  List<String> getCodes(Integer num);

  /**
   * 查询上传码
   *
   * @return 上传码列表
   */
  List<String> searchCodes();

  /**
   * 上传至 oss
   *
   * @param entry oss必备参数
   * @return 上传回调地址
   */
  String oss(OssRequiredEntry entry);

  /**
   * 多文件直接上传至 OSS 不需要分片等操作
   *
   * @return 地址列表
   */
  List<String> directCloud(DirectUploaderFilesInfo filesInfo);

  /**
   * 删除文件
   *
   * @param dto 文件值对象
   * @return 是否删除成功
   */
  boolean deleteFile(FileDTO dto);

  /**
   * 获取缓存键值
   *
   * @param filename 文件名
   * @return 缓存键
   */
  default String getCacheKey(String filename) {
    return FileCacheKey.FILE_CACHE_PREFIX + "::" + filename;
  }

  /**
   * 获取上传缓存键值
   *
   * @param username 用户名
   * @param md5 md5
   * @return 返回缓存键值
   */
  default String uploadCacheKey(String md5, String username) {
    return FileCacheKey.FILE_UPLOAD_CACHE + "::" + username + "::" + md5;
  }

  /**
   * 检查上传码
   *
   * @param uploadCode 上传码
   * @return 检查结果
   */
  default boolean checkUploadCode(String uploadCode) {
    // 校验上传码是否为空
    if (StringUtils.isBlank(uploadCode)) {
      throw new FileException(FileStatus.UPLOAD_CODE_IS_NULL);
    }
    // 校验上传码是否存在
    List<String> codes = searchCodes();
    if (!codes.contains(uploadCode)) {
      throw new FileException(FileStatus.UPLOAD_CODE_IS_NOT_FOUND);
    }
    return true;
  }
}
